"use client";

import { Alert, AlertDescription, AlertTitle } from "@components/ui/alert";
import { Button } from "@components/ui/button";
import { CardHeader } from "@components/ui/card";
import { Checkbox } from "@components/ui/checkbox";
import { FormControl } from "@components/ui/form-control";
import { Heading } from "@components/ui/heading";
import { Link } from "@components/ui/link";
import { magicModal } from "@components/ui/magic-modal";
import { Page } from "@components/ui/page";
import { Switch } from "@components/ui/switch";
import { Textarea } from "@components/ui/textarea";
import { toast } from "@components/ui/toaster/use-toast";
import { useReactQueryInvalidateQueries } from "@hooks/use-invalidate-queries";
import * as ToggleGroup from "@radix-ui/react-toggle-group";
import { PARAMETERS_PATHS } from "@services/parameters";
import { createOrUpdateCodeReviewParameter } from "@services/parameters/fetch";
import {
    KodyLearningStatus,
    ParametersConfigKey,
} from "@services/parameters/types";
import { EyeIcon, Save } from "lucide-react";
import { Controller, useFormContext } from "react-hook-form";
import { useSelectedTeamId } from "src/core/providers/selected-team-context";

import { CodeReviewPagesBreadcrumb } from "../../_components/breadcrumb";
import GeneratingConfig from "../../_components/generating-config";
import { PRSummaryPreviewModal } from "../../_components/pr-summary-preview-modal/modal";
import {
    BehaviourForNewCommits,
    CodeReviewSummaryOptions,
    type AutomationCodeReviewConfigPageProps,
    type CodeReviewFormType,
} from "../../_types";
import {
    useCodeReviewConfig,
    usePlatformConfig,
} from "../../../_components/context";
import { useCodeReviewRouteParams } from "../../../_hooks";

const examples = [
    "Focus on security changes and performance impacts",
    "Summarize concisely, highlighting modified public APIs",
];

const reviewOptions = [
    {
        default: true,
        value: CodeReviewSummaryOptions.REPLACE,
        name: "Replace",
        description: "Generates a new description from scratch",
    },
    {
        value: CodeReviewSummaryOptions.CONCATENATE,
        name: "Concatenate",
        description:
            "Adds the generated summary to the end of the existing description",
    },
    {
        value: CodeReviewSummaryOptions.COMPLEMENT,
        name: "Complement",
        description:
            "Combines insights generated by Kody with the current description, highlighting only what is new or relevant",
    },
] as const;

const behaviorForCommitsAfterPROpenedOptions = [
    {
        default: true,
        value: BehaviourForNewCommits.NONE,
        name: "Do nothing",
        description: "No action will be taken",
    },
    {
        value: BehaviourForNewCommits.REPLACE,
        name: "Replace Kody’s summary",
        description: "Replaces the existing summary with a new one",
    },
    {
        value: BehaviourForNewCommits.CONCATENATE,
        name: "Concatenate new summary",
        description: "Adds the new summary to the existing one",
    },
] as const;

export default function PRSummary(props: AutomationCodeReviewConfigPageProps) {
    const { teamId } = useSelectedTeamId();
    const config = useCodeReviewConfig();
    const platformConfig = usePlatformConfig();
    const { repositoryId, directoryId } = useCodeReviewRouteParams();
    const form = useFormContext<CodeReviewFormType>();

    const generatePRSummary = form.watch("summary.generatePRSummary");

    const { resetQueries, generateQueryKey } = useReactQueryInvalidateQueries();

    const handleSubmit = form.handleSubmit(async (config) => {
        try {
            await createOrUpdateCodeReviewParameter(
                config,
                teamId,
                repositoryId,
                directoryId,
            );

            await resetQueries({
                queryKey: generateQueryKey(PARAMETERS_PATHS.GET_BY_KEY, {
                    params: {
                        key: ParametersConfigKey.CODE_REVIEW_CONFIG,
                        teamId,
                    },
                }),
            });

            form.reset(config);

            toast({
                description: "Settings saved",
                variant: "success",
            });
        } catch (error) {
            console.error("Erro ao salvar as configurações:", error);

            toast({
                title: "Error",
                description:
                    "An error occurred while saving the settings. Please try again.",
                variant: "danger",
            });
        }
    });

    const {
        isDirty: formIsDirty,
        isValid: formIsValid,
        isSubmitting: formIsSubmitting,
    } = form.formState;

    if (
        platformConfig.kodyLearningStatus ===
        KodyLearningStatus.GENERATING_CONFIG
    ) {
        return <GeneratingConfig />;
    }

    return (
        <Page.Root>
            <Page.Header>
                <CodeReviewPagesBreadcrumb pageName="PR summary" />
            </Page.Header>

            <Page.Header>
                <Page.Title>PR summary</Page.Title>

                <Page.HeaderActions>
                    <Button
                        size="md"
                        variant="primary"
                        leftIcon={<Save />}
                        onClick={handleSubmit}
                        disabled={!formIsDirty || !formIsValid}
                        loading={formIsSubmitting}>
                        Save settings
                    </Button>
                </Page.HeaderActions>
            </Page.Header>

            <Page.Content className="gap-8">
                <Controller
                    name="summary.generatePRSummary"
                    control={form.control}
                    render={({ field }) => (
                        <Button
                            size="sm"
                            variant="helper"
                            onClick={() => field.onChange(!field.value)}
                            className="w-full">
                            <CardHeader className="flex flex-row items-center justify-between">
                                <div className="flex flex-col gap-1">
                                    <Heading variant="h3">
                                        Enable Automatic Summary Generation
                                    </Heading>
                                </div>

                                <Switch
                                    size="md"
                                    decorative
                                    checked={field.value}
                                />
                            </CardHeader>
                        </Button>
                    )}
                />
                <Controller
                    name="summary.behaviourForNewCommits"
                    control={form.control}
                    render={({ field }) => (
                        <FormControl.Root>
                            <FormControl.Label className="mb-0">
                                Behavior for commits after PR is opened
                            </FormControl.Label>

                            <FormControl.Helper className="mb-3">
                                You can define Kody's behavior in relation to
                                commits after the PR is opened.
                            </FormControl.Helper>

                            <FormControl.Input>
                                <ToggleGroup.Root
                                    type="single"
                                    value={field.value}
                                    className="grid grid-cols-1 gap-2 sm:grid-cols-2 md:grid-cols-3"
                                    disabled={!generatePRSummary}
                                    onValueChange={(value) => {
                                        if (!value) return;
                                        field.onChange(value);
                                    }}>
                                    {behaviorForCommitsAfterPROpenedOptions.map(
                                        (option) => (
                                            <ToggleGroup.ToggleGroupItem
                                                asChild
                                                key={option.value}
                                                value={option.value}
                                                aria-label={option.name}>
                                                <Button
                                                    size="lg"
                                                    variant="helper"
                                                    className="w-full items-start py-4">
                                                    <div className="flex items-start justify-between gap-6 w-full">
                                                        <div className="flex flex-col gap-2">
                                                            <Heading
                                                                variant="h3"
                                                                className="truncate">
                                                                {option.name}
                                                                {"default" in
                                                                    option && (
                                                                    <small className="text-text-secondary ml-1">
                                                                        (default)
                                                                    </small>
                                                                )}
                                                            </Heading>

                                                            <p className="text-text-secondary text-xs">
                                                                {
                                                                    option.description
                                                                }
                                                            </p>
                                                        </div>

                                                        <Checkbox
                                                            decorative
                                                            checked={
                                                                option.value ===field.value
                                                            }
                                                        />
                                                    </div>
                                                </Button>
                                            </ToggleGroup.ToggleGroupItem>
                                        ),
                                    )}
                                </ToggleGroup.Root>
                            </FormControl.Input>
                        </FormControl.Root>
                    )}
                />

                <Controller
                    name="summary.behaviourForExistingDescription"
                    control={form.control}
                    render={({ field }) => (
                        <FormControl.Root>
                            <FormControl.Label className="mb-0">
                                Behavior for Existing Description
                            </FormControl.Label>

                            <FormControl.Helper className="mb-3">
                                You can define Kody's behavior in relation to
                                the descriptions already present in the PR.
                            </FormControl.Helper>

                            <FormControl.Input>
                                <ToggleGroup.Root
                                    type="single"
                                    disabled={!generatePRSummary}
                                    className="grid grid-cols-1 gap-2 sm:grid-cols-2 md:grid-cols-3"
                                    value={field.value}
                                    onValueChange={(value) => {
                                        if (!value) return;
                                        field.onChange(
                                            value as CodeReviewSummaryOptions,
                                        );
                                    }}>
                                    {reviewOptions.map((option) => (
                                        <ToggleGroup.ToggleGroupItem
                                            asChild
                                            key={option.value}
                                            value={option.value}>
                                            <Button
                                                size="lg"
                                                variant="helper"
                                                className="w-full items-start py-4">
                                                <div className="flex items-start justify-between gap-6">
                                                    <div className="flex flex-col gap-2">
                                                        <Heading
                                                            variant="h3"
                                                            className="truncate">
                                                            {option.name}

                                                            {"default" in
                                                                option && (
                                                                <small className="text-text-secondary ml-1">
                                                                    (default)
                                                                </small>
                                                            )}
                                                        </Heading>

                                                        <p className="text-text-secondary text-xs">
                                                            {option.description}
                                                        </p>
                                                    </div>

                                                    <Checkbox
                                                        decorative
                                                        checked={
                                                            option.value ===
                                                            field.value
                                                        }
                                                    />
                                                </div>
                                            </Button>
                                        </ToggleGroup.ToggleGroupItem>
                                    ))}
                                </ToggleGroup.Root>
                            </FormControl.Input>
                        </FormControl.Root>
                    )}
                />

                <Controller
                    name="summary.customInstructions"
                    control={form.control}
                    render={({ field }) => (
                        <FormControl.Root>
                            <FormControl.Label
                                className="mb-0"
                                htmlFor={field.name}>
                                Custom Instructions
                            </FormControl.Label>
                            <FormControl.Helper className="mb-3">
                                You can customize how Kody generates your
                                summaries.
                            </FormControl.Helper>

                            <Alert className="mb-3">
                                <AlertTitle>Examples</AlertTitle>
                                <AlertDescription className="space-y-2">
                                    {examples.map((example) => (
                                        <li key={example}>
                                            <Link
                                                href=""
                                                disabled={!generatePRSummary}
                                                onClick={(e) => {
                                                    e.preventDefault();

                                                    const newInstructions =
                                                        field.value
                                                            ? `${field.value}\n${example}`
                                                            : example;

                                                    field.onChange(
                                                        newInstructions,
                                                    );
                                                }}>
                                                {example}
                                            </Link>
                                        </li>
                                    ))}
                                </AlertDescription>
                            </Alert>

                            <FormControl.Input>
                                <Textarea
                                    value={field.value}
                                    disabled={!generatePRSummary}
                                    id={field.name}
                                    className="min-h-48"
                                    placeholder="Write the instructions here"
                                    onChange={(e) =>
                                        field.onChange(e.target.value)
                                    }
                                />
                            </FormControl.Input>
                        </FormControl.Root>
                    )}
                />

                <div className="-mt-3 flex justify-end">
                    <Button
                        size="md"
                        variant="helper"
                        leftIcon={<EyeIcon />}
                        disabled={!generatePRSummary}
                        onClick={() => {
                            const behaviourForExistingDescription =
                                form.getValues(
                                    "summary.behaviourForExistingDescription",
                                );

                            const customInstructions = form.getValues(
                                "summary.customInstructions",
                            );

                            magicModal.show(() => (
                                <PRSummaryPreviewModal
                                    repositoryId={props.repositoryId}
                                    customInstructions={customInstructions!}
                                    repositoryName={config?.name!}
                                    behaviourForExistingDescription={
                                        behaviourForExistingDescription!
                                    }
                                />
                            ));
                        }}>
                        View Preview
                    </Button>
                </div>
            </Page.Content>
        </Page.Root>
    );
}
